package com.test.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class EchoClient {
	public static void main(String[] args) {
		// First parameter has to be machine name
		// if (args.length == 0) {
		// System.out.println("Usage : EchoClient <serverName>");
		// return;
		// }

		Socket s = null;
		Monitor monitor = null;

		// Create the socket connection to the EchoServer.
		try {
			// s = new Socket(args[0], EchoServer.SERVER_PORT);
			String server = "127.0.0.1";
			s = new Socket(server, EchoServer.SERVER_PORT);
			System.out.printf("The server[%s:%s] is connected.\n", server, EchoServer.SERVER_PORT);
			//monitor = new Monitor(s);
		} catch (UnknownHostException uhe) {
			// Host unreachable
			System.out.println("Unknown Host :" + EchoServer.SERVER_PORT);
			s = null;
		} catch (IOException ioe) {
			// Cannot connect to port on given host
			System.out.printf("\nCant connect to server at %d. Make sure it is running.", EchoServer.SERVER_PORT);
			s = null;
		}

		if (s == null)
			System.exit(-1);

		BufferedReader in = null;
		PrintWriter out = null;

		try {
			// Create the streams to send and receive information
			in = new BufferedReader(new InputStreamReader(s.getInputStream()));
			out = new PrintWriter(new OutputStreamWriter(s.getOutputStream()));

			System.out.println("Server Says : " + in.readLine());

			// // Since this is the client, we will initiate the talking.
			// // Send a string.
			// out.println("Hello");
			// out.flush();

			try {
				Thread.sleep(5 * 1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("wake up.");
			// Send the special string to tell server to quit.
			// out.println("Quit");
			// out.flush();
		} catch (IOException ioe) {
			System.out.println("Exception during communication. Server probably closed connection.");
		} finally {
			try {
				// Close the streams
				out.close();
				in.close();
				// Close the socket before quitting
				s.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		if (monitor != null)
			monitor.stop();
		System.out.println("Closed.");
	}
}

class Monitor implements Runnable {

	private PrintWriter out;
	private ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

	public Monitor(Socket connection) {
		try {
			this.out = new PrintWriter(new OutputStreamWriter(connection.getOutputStream()));
		} catch (IOException e) {
			e.printStackTrace();
		}
		scheduler.scheduleAtFixedRate(this, 1, 1, TimeUnit.SECONDS);
	}

	@Override
	public void run() {
		try {
			System.out.println("Sending heartbeat...");
			out.println("HB");
			out.flush();
			System.out.println("Heartbeat sent successfully.");
		} catch (Throwable t) {
			t.printStackTrace();
		}

	}

	public void stop() {
		scheduler.shutdown();
	}
}